<?php
/**
 * 缓存条目
 *
 * @version $Id$
 * @package if
 * @subpackage module.cache
 */
class ICacheEntry extends IObject {
	private $key;
	private $modified;
	private $visited;
	private $maxAge;
	private $value;
	private $ttl;
	private $tags = array();
	private $tagIds = array();
	/**
	 * Enter description here...
	 *
	 * @var ICacheEngine
	 * @since 1.0.1
	 */
	private $engine;
	
	/**
	 * 构造器
	 *
	 * @param array $opts 对缓存条目的配置
	 * @since 1.0
	 */
	function __construct(array $opts = null) {
		if (is_array($opts)) {
			foreach ($opts as $key=>$opt) {
				if (in_array(strtolower($key), array("key", "modified", "visited", "maxage", "value", "ttl", "tags", "tagids"))) {
					$method = "set" . $key;
					$this->$method($opt);
				}
			}
		}
	}
	
	/**
	 * 清空值
	 *
	 * @since 1.0
	 */
	function clear() {
		$this->modified = $this->_time();
		$this->value = null;
	}
	
	/**
	 * 取得键
	 *
	 * @return string
	 * @since 1.0
	 */	
	function key() {
		return $this->key;
	}
	
	/**
	 * 取得最后修改时间
	 *
	 * @return integer
	 * @since 1.0
	 */	
	function modified() {
		return $this->modified;
	}
	
	/**
	 * 取得最后访问时间
	 *
	 * @return integer
	 * @since 1.0
	 */	
	function visited() {
		if (!$this->visited) {
			$this->visited = $this->_time();
		}
		return $this->visited;
	}
	
	/**
	 * 取得最大生存期
	 *
	 * @return integer
	 * @since 1.0
	 */	
	function maxAge() {
		return $this->maxAge;
	}
	
	/**
	 * 取得刷新时间间隔
	 *
	 * @return integer
	 * @since 1.0
	 */	
	function ttl() {
		return $this->ttl;
	}
	
	/**
	 * 取得值
	 *
	 * @return mixed
	 * @since 1.0
	 */	
	function value() {
		if ($this->expired()) {
			$this->clear();
		}
		return $this->value;
	}
	
	/**
	 * 判断当前缓存条目是否过期
	 *
	 * @return boolean
	 * @since 1.0
	 */
	function expired() {
		$now = $this->_time();
		if (is_int($this->maxAge) && $this->maxAge !== 0 && $this->maxAge < $now) {
			return true;
		}
		if (is_int($this->ttl) && $this->ttl > 0 && $this->modified + $this->ttl < $now) {
			return true;
		}
		//检查tag
		if (!empty($this->tags) && $this->engine) {
			foreach ($this->tags as $key => $tag) {
				if (!isset($this->tagIds[$key])) {
					return true;
				}
				$tagId = $this->tagIds[$key];
				if ($this->engine->read("TAG$$$" . $tag) != $tagId) {
					return true;
				}
			}
		}
		return false;
	}
	
	/**
	 * 设置键
	 *
	 * @param string $key 键
	 * @since 1.0
	 */	
	function setKey($key) {
		$this->key = $key;
	}
	
	/**
	 * 设置最后修改时间
	 *
	 * @param integer $modified 时间戳
	 * @since 1.0
	 */	
	function setModified($modified) {
		$this->modified = $modified;	
	}
	
	/**
	 * 设置最后访问时间
	 *
	 * @param integer $visited 时间戳
	 * @since 1.0
	 */
	function setVisited($visited) {
		$this->visited = $visited;
	}
	
	/**
	 * 设置最大生存期
	 *
	 * @param integer $maxAge 时间戳
	 * @since 1.0
	 */
	function setMaxAge($maxAge) {
		$this->maxAge = $maxAge;
		$now = $this->_time();
		if (!is_null($this->maxAge) && $this->maxAge !== 0 && $this->maxAge < $now) {
			$this->clear();
		}
	}
	
	/**
	 * 设置刷新间隔
	 *
	 * @param integer $ttl 刷新间隔
	 * @since 1.0
	 */
	function setTtl($ttl) {
		$this->ttl = $ttl;
	}
	
	/**
	 * 设置值
	 *
	 * @param mixed $value 值
	 * @since 1.0
	 */
	function setValue($value) {
		$this->value = $value;
	}
	
	/**
	 * 转换为数组
	 *
	 * @return array
	 * @since 1.0
	 */
	function asArray() {
		return array(
			"key" => $this->key, 
			"modified" => $this->modified, 
			"visited" => $this->visited, 
			"maxAge" => $this->maxAge, 
			"value" => $this->value, 
			"ttl" => $this->ttl,
			"tags" => $this->tags,
			"tagIds" => $this->tagIds
		);
	}
	
	/**
	 * 设置该条目关联的tag
	 * 
	 * 用来方便整体删除相关tag的条目
	 *
	 * @param array|string $tags 数组或用空格、逗号、分号隔开的字符串
	 * @since 1.0.1
	 */
	function setTags($tags) {
		if (!is_array($tags)) {
			$tags = preg_split("/[\s,;]+/", $tags);
		}
		$this->tags = array_unique($tags);
	}
	
	/**
	 * 设置TAG的ID
	 *
	 * @param array $tagIds 一组TAG ID
	 * @since 1.0.1
	 */
	function setTagIds($tagIds) {
		$this->tagIds = $tagIds;
	}
	
	/**
	 * 取得条目关联的tags
	 *
	 * @return array
	 * @since 1.0.1
	 */
	function tags() {
		return $this->tags;
	}
	
	/**
	 * 设置当前条目要保存到的缓存引擎
	 *
	 * @param ICacheEngine $engine 缓存引擎
	 * @since 1.0.1
	 */
	function setEngine(ICacheEngine $engine) {
		$this->engine = $engine;
	}
	
	/**
	 * 保存当前条目到缓存引擎
	 *
	 * @since 1.0.1
	 */
	function save() {
		if ($this->engine) {
			$this->engine->writeEntry($this);
		}
	}
	
	/**
	 * 从当前缓存引擎中删除该条目
	 *
	 * @since 1.0.1
	 */
	function delete() {
		if ($this->engine) {
			$this->engine->delete($this->key);
		}
	}
	
	/**
	 * 将当前条目写入到某个缓存引擎
	 * 
	 * 缓存引擎可以由：
	 * <code>
	 * ICache::engine("缓存引擎名");
	 * </code>
	 * 获得
	 *
	 * @param ICacheEngine $engine 缓存引擎
	 * @since 1.0.1
	 */
	function writeTo(ICacheEngine $engine) {
		$engine->writeEntry($engine);
	}
}

?>